/*
 * 任务管理
 *
 * author: lishutong
 * site: https://lishutong1024.cn / https://lishutong1024.github.cn
 */
#ifndef OS_TASK_H
#define OS_TASK_H

#include "os_plat.h"
#include "os_err.h"
#include "os_def.h"
#include "os_list.h"
#include "os_event.h"

#define	OS_TASK_STATE_RDY					(1 << 8)
#define	OS_TASK_STATE_DELAYED				(1 << 9)
#define OS_TASK_STATE_SUSPEND               (1 << 10)
#define OS_TASK_STATE_WAIT                  (1 << 11)

#define OS_TASK_STACK_FILL              0xAA      // 栈检查填充字节

/**
 * 任务等待的对像结构
 */
typedef struct _task_wait_t {
    os_event_t * event;             // 等待的
    void * reason;                  // 等待的原因
    os_err_t err;                   // 等待结果
}task_wait_t;

void task_wait_init (task_wait_t * wait, os_event_t * event, void * reason);

/**
 * 任务运行的入口函数
 */
typedef void (*task_entry_t)(void *);

/**
 * 任务结构
 */
typedef struct _os_task_t {
    char name[OS_TASK_NAME_SIZE];       // 任务名称[

#if OS_TASK_INFO_ENABLE || OS_SCHED_CHECK_TASK_STACK
    cpu_stack_t * start_stack;          // 栈的起始地址
    int stack_size;                     // 栈的大小
#endif
    os_task_ctx_t ctx;                // 任务的当前上下文
    int delay_tick;                     // 延时计数器
    uint16_t prio;                      // 优先级
    uint16_t flags;                     // 一些标志位
#if OS_SCHED_RR_ENABLE
    int slice;                          // 时间片
#endif

    os_list_item_t info_item;           // 所有任务的链接结点
    os_list_item_t run_item;            // 链接结构

    task_wait_t event_wait;               // 等待的事件
    os_list_item_t event_item;          // 等待的结点
}os_task_t;

os_task_t * os_task_create (const char * name, task_entry_t entry, void *param,
                    int prio, int stack_size);
os_err_t os_task_init (os_task_t * task, const char * name, task_entry_t entry, void * param,
                int prio, void * stack, int stack_size);
void os_task_start (os_task_t * task);
void os_task_exit (void);
void os_task_sleep (int ms);
os_err_t os_task_suspend (os_task_t * task);
os_err_t os_task_resume (os_task_t * task);

/**
 * 任务栈信息
 */
typedef struct _os_task_stack_info_t {
    cpu_stack_t * stack;                // 栈起始地址
    int stack_size;                     // 栈空间总字节数
    int unused;                         // 未使用的字节数
}os_task_stack_info_t;

os_err_t os_task_stack_info (os_task_t * task, os_task_stack_info_t * info);

#endif /* OS_TASK_H */
